package com.friends.common.web.interceptor;

import com.friends.common.tools.util.Tools;
import com.friends.common.web.annotation.Token;
import com.friends.common.web.exception.ResubmitException;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;

/**
 * 防表单form重复提交拦截器
 *
 * Created by xiajiangge on 2017/2/19.
 */
public class TokenInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {
            HttpSession session = request.getSession();
            HandlerMethod handlerMethod = (HandlerMethod)handler;
            Method method = handlerMethod.getMethod();
            Token annotation = method.getAnnotation(Token.class);
            if (annotation != null ) {
                boolean needSaveSession = annotation.save();
                if (needSaveSession) {
                    session.setAttribute("token", Tools.getUUID());
                    return true;
                }
                boolean needRemoveSession = annotation.remove();
                synchronized (session) {
                    if (needRemoveSession) {
                        if (isRepeatSubmit(request)) {
                            throw new ResubmitException("重复提交或未获取令牌");
                        }
                        session.setAttribute("token", Tools.getUUID());
                    }
                }
            }
            return true ;
        } else {
            return super.preHandle(request,response,handler);
        }
    }

    private boolean isRepeatSubmit(HttpServletRequest request) {
        String serverToken = (String)request.getSession().getAttribute("token");
        if (serverToken == null) {
            return true;
        }
        String clinetToken = request.getParameter("token");
        if (clinetToken == null) {
            return true;
        }
        if (!serverToken.equals(clinetToken)) {
            return true;
        }
        return false;
    }
}
